package com.toocms.tab.base;

import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.databinding.DataBindingUtil;
import androidx.databinding.ViewDataBinding;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModel;
import androidx.lifecycle.ViewModelProvider;

import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.ScreenUtils;
import com.toocms.tab.R;
import com.toocms.tab.TooCMSApplication;
import com.toocms.tab.bus.Messenger;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @Description:
 * @Author: Zero
 * @CreateDate: 2023/1/20 16:32
 */
public abstract class BaseDialogFragment<V extends ViewDataBinding, VM extends BaseViewModel> extends DialogFragment {

    protected V binding;
    protected VM viewModel;

    protected abstract void onFragmentCreated();

    protected abstract @LayoutRes
    int getLayoutResId();

    public abstract int getVariableId();

    protected abstract void viewObserver();

    protected abstract boolean isMiddleDialog();

    // 非最后一层子类传入V和VM需重写该回调方法
    protected VM getViewModel() {
        return null;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setStyle(DialogFragment.STYLE_NO_TITLE, isMiddleDialog() ? R.style.dialog_fullscreen_middle_style : R.style.dialog_fullscreen_bottom_style);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        binding = DataBindingUtil.inflate(inflater, getLayoutResId(), container, false);
        return binding.getRoot();
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        //初始化DataBinding和ViewModel
        initVVM();
        //注册ViewModel与View的契约事件回调逻辑
        registerUIChangeLiveDataCallBack();
        //页面数据初始化方法
        onFragmentCreated();
        //页面事件监听的方法，一般用于ViewModel层转到View层的事件注册
        viewObserver();
        //注册RxBus
        viewModel.registerRxBus();
    }

    @Override
    public void onStart() {
        WindowManager.LayoutParams params = getDialog().getWindow().getAttributes();
        params.width = ScreenUtils.getScreenWidth() - (isMiddleDialog() ? ConvertUtils.dp2px(60) : 0);
        params.gravity = isMiddleDialog() ? Gravity.CENTER_VERTICAL : Gravity.BOTTOM;
        getDialog().getWindow().setAttributes(params);
        super.onStart();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Messenger.getDefault().unregister(viewModel);
        if (viewModel != null) {
            viewModel.removeRxBus();
        }
        if (binding != null) {
            binding.unbind();
        }
    }

    // 注入绑定
    private void initVVM() {
        viewModel = getViewModel();
        if (viewModel == null) {
            Class modelClass;
            Type type = getClass().getGenericSuperclass();
            if (type instanceof ParameterizedType) {
                modelClass = (Class) ((ParameterizedType) type).getActualTypeArguments()[1];
            } else {
                //如果没有指定泛型参数，则默认使用BaseViewModel
                modelClass = BaseViewModel.class;
            }
            viewModel = (VM) createViewModel(this, modelClass);
        }
        binding.setVariable(getVariableId(), viewModel);
        //支持LiveData绑定xml，数据改变，UI自动会更新
        binding.setLifecycleOwner(this);
        //让ViewModel拥有View的生命周期感应
        getLifecycle().addObserver(viewModel);
    }

    public <T extends ViewModel> T createViewModel(Fragment fragment, Class<T> cls) {
        return new ViewModelProvider(fragment, ViewModelProvider.AndroidViewModelFactory.getInstance(TooCMSApplication.getInstance())).get(cls);
    }

    // 注册ViewModel与View的契约UI回调事件
    protected void registerUIChangeLiveDataCallBack() {
        // 关闭Fragment
        viewModel.getUiChangeLiveData().getFinishFragmentEvent().observe(this, v -> dismiss());
    }
}
